#pragma once 
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
using namespace std;

class tcpclient
{
public:
    tcpclient(const string& ip,const uint16_t port)
    :_sockfd(-1),_serverip(ip),_serverport(port)
    {
    }
    void initclient()
    {
        //创建套接字
        _sockfd = socket(AF_INET,SOCK_STREAM,0);
        if(_sockfd < 0)
        {
            cerr<<"socket fail"<<endl;
            exit(2);
        }
        //客户端是需要bind,但是不需要我们显示的bind，OS会自动帮我们bind，会在合适的时机
        //更不要监听工作，因为你是客服端，你是要连接服务器，其他的事不需要去做
    }
    void start()
    {
        //既然要连接服务器，那么我们肯定是需要获得服务器的基本信息
        struct sockaddr_in server;
        memset(&server,0,sizeof(server));
        server.sin_addr.s_addr = inet_addr(_serverip.c_str());
        server.sin_family = AF_INET;
        server.sin_port = htons(_serverport);
        //开始连接
        if(connect(_sockfd,(struct sockaddr*)&server,sizeof(server)) != 0)
        {
            //连接失败，继续尝试连接
            cerr<<"connect fail"<<endl;
        }
        else
        {
            string message;
            while(true)
            {
                cout<<"Enter# "<<endl;
                getline(cin,message);
                //开始发送往服务器
                write(_sockfd,message.c_str(),message.size());
                //读到服务器发来的消息
                char buffer[1024];
                ssize_t n = read(_sockfd,buffer,sizeof(buffer));
                if(n > 0)
                {
                    //接受
                    buffer[n] = 0;
                    cout<<"服务器发来信息："<<buffer<<endl;
                }
                else{
                    break;
                }
            }
        }
    }
    ~tcpclient()
    {
        //这里可以关闭文件描述符，也可以不关闭，因为文件描述符随进程，进程退出OS必定回收
        close(_sockfd);
    }
private:
    string _serverip;   //服务器ip
    uint16_t _serverport;   //服务器端口号
    int _sockfd; // 套接字
};